package com.telit.firecommand.facade;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.push.model.v20160801.PushResponse;
import com.telit.common.constant.MsgConstants;
import com.telit.common.constant.MsgIdentificationConstants;
import com.telit.common.constant.NoticeTypeConstants;
import com.telit.common.constant.RoleCodeConstants;
import com.telit.common.entity.DataReturn;
import com.telit.common.enums.ResultCode;
import com.telit.common.exception.ForestBaseException;
import com.telit.common.pojo.AliPushContentPojo;
import com.telit.common.util.*;
import com.telit.communicate.dto.SendMessageDTO;
import com.telit.communicate.feign.RemoteCommunicateService;
import com.telit.firecommand.constant.RedisKeyConstant;
import com.telit.firecommand.dao.*;
import com.telit.firecommand.dto.*;
import com.telit.firecommand.entity.*;
import com.telit.firecommand.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author yuzhanxiang
 * @description: 添加火情
 * @copyright 天立泰科技股份有限公司
 * @since 2022/4/22 17:47
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class FireTriggerFacadeService {

    @Value("${fire.limitDistance}")
    private String limitDistance;

    @Value("${weather.address}")
    private String address;

    @Value("${forest.enablePushFireSms}")
    private String enablePushFireSms;

    private final CommFireAlarmDao commFireAlarmDao;

//    private final ICommFireOnemapService commFireOnemapService;

    private final GeoXzqhCunDao geoXzqhCunDao;

    private final WeatherService weatherService;

    private final FireWeatherInfoDao fireWeatherInfoDao;

    private final GeoQueryService geoQueryService;

    private final BusinessTableDao businessTableDao;

    private final ApplicationContext applicationContext;

    private final RemoteCommunicateService communicateFeignClient;

    private final CameraInfoService cameraInfoService;

    private final FireAdminService fireAdminService;

    private final CommMsgCenterLogDao commMsgCenterLogDao;

    private final MsgService msgService;

    private final com.telit.firecommand.facade.SmsPushUriPubFacadeService smsPushUriPubFacadeService;

//    private final OperationFeignClient operationFeignClient;

    private final com.telit.firecommand.facade.VoicePushFacadeService voicePushFacadeService;

    private final SysUserDAO sysUserDAO;

    private final ICommFireOnemapService commFireOnemapService;

    /**
     * 添加火情
     *
     * @param fireAlarm 火情对象
     * @param request   请求
     */
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    // @CacheEvict(value = {"firecommand:firealarm:queryLeftFireInfo","firecommand:firealarm:queryUnFinishFireNum","firecommand:fire:queryTelephoneAlarmByDistrictCode","firecommand:fire:queryAllTelephoneAlarm","firecommand:fire:queryAllFireByCondition","firecommand:fire:queryUnfinishedFireByDay","firecommand:resoure:selectFireAndEventCountByDistrictCode","firecommand:firealarm:selectFireCountBySourceByDistrictCode"},allEntries = true)
    public void addFire(CommFireAlarm fireAlarm, HttpServletRequest request) {
        final TimeInterval timeInterval = DateUtil.timer();
        //重复火情判断   实体被深clone 校验阶段不会改变
        //  repeatFireInfoChecked(fireAlarm);
        log.info("add fire step 1.完成重复火情校验逻辑,用时[{}]毫秒,fireAlarm[{}]", timeInterval.intervalRestart(),
                JSONUtil.toJsonPrettyStr(fireAlarm));
        //构造火情数据 --- 数据执行完下述方法将可能发生变化
        buildFireData(fireAlarm);
        log.info("add fire step 2.完成火情数据构造,用时[{}]毫秒,fireAlarm[{}]", timeInterval.intervalRestart(),
                JSONUtil.toJsonPrettyStr(fireAlarm));
        //插入火情数据
        commFireAlarmDao.insertSelective(fireAlarm);
        log.info("add fire step 3.完成火情数据插入--未commit,用时[{}]毫秒,fireAlarm[{}]", timeInterval.intervalRestart(),
                JSONUtil.toJsonPrettyStr(fireAlarm));
        //查询一张图数据并插入
        insertOneMapInfo(fireAlarm);
        log.info("add fire step 4.完成一张图数据插入--未commit,用时[{}]毫秒,fireAlarm[{}]", timeInterval.intervalRestart(),
                JSONUtil.toJsonPrettyStr(fireAlarm));
        //插入火情天气关联表数据
        insertWeatherInfo(fireAlarm.getId());
        log.info("add fire step 5.完成火情天气关联表数据--未commit,用时[{}]毫秒,fireAlarm[{}]", timeInterval.intervalRestart(),
                JSONUtil.toJsonPrettyStr(fireAlarm));
        //判断电话接警的已有火情除外
        if (fireAlarm.getOriginFireId() == null || fireAlarm.getOriginFireId() == 0) {
            insertBusinessTable(fireAlarm);
        }
        log.info("add fire step 6.完成火情主表信息关联表数据--未commit,用时[{}]毫秒,fireAlarm[{}]", timeInterval.intervalRestart(),
                JSONUtil.toJsonPrettyStr(fireAlarm));
        //三端推送执行逻辑
        if ((fireAlarm.getOriginFireId() == null || fireAlarm.getOriginFireId() == 0) && !"3".equals(
                fireAlarm.getFireJudgmentType())) {
            if ("6".equals(fireAlarm.getResource())) {
                //获取web端管理员上报电话接警人的名字
                //    String realName = JwtTokenUtils.getRealName();
                //设置到火情传输对象中
                //   fireAlarm.setMobileReceiverName(realName);
            }
            applicationContext.publishEvent(JSONUtil.toJsonStr(fireAlarm));
            log.info("add fire step 7.发起三端推送异步触发器,用时[{}]毫秒,fireAlarm[{}]", timeInterval.intervalRestart(),
                    JSONUtil.toJsonPrettyStr(fireAlarm));
        }
    }

    @Async
    @EventListener
    public void pushAliSms(String msg) {
        if (!BooleanUtil.toBoolean(enablePushFireSms)) {
            return;
        }
        
        log.info("阿里云短信推送-推送时间[{}]-火情推送触发,msg[{}]", DateUtil.now(), msg);
        final CommFireAlarm alarm = JSONUtil.toBean(msg, CommFireAlarm.class);
        if (ObjectUtil.isNull(alarm)) {
            log.error("阿里云短信推送失败,火情信息解析失败:msg[{}]", msg);
            return;
        }
        //获取短信推送内容
        final AliPushSmsEventDto aliPushSmsEventDto = buildDtoForAliSms(alarm);
        try {
            if (ObjectUtil.isNotNull(aliPushSmsEventDto.getAliH5SmsPushDto())) {
                final List<String> mobs = aliPushSmsEventDto.getAliH5SmsPushDto().getMobiles()
                        .stream()
                        .filter(Validator::isMobile)
                        .distinct()
                        .collect(Collectors.toList());
                log.info("本次短信计划发送:[{}]人，过滤无效手机号去重后，剩余[{}]人，明细[{}]",
                        aliPushSmsEventDto.getAliH5SmsPushDto().getMobiles().size()
                        , mobs.size()
                        , JSONUtil.toJsonStr(aliPushSmsEventDto.getAliH5SmsPushDto().getMobiles()));
                if (CollUtil.isNotEmpty(mobs)) {
                    smsPushUriPubFacadeService.sendSms(aliPushSmsEventDto.getAliH5SmsPushDto().getFireId(),
                            mobs, aliPushSmsEventDto.getAliH5SmsPushDto().getStatus());
                    log.info("真实或疑似火情推送短信已完成");
                }
            }
            if (ObjectUtil.isNotNull(aliPushSmsEventDto.getAliCameraSmsPushDto())) {
                final List<String> mobs = aliPushSmsEventDto.getAliCameraSmsPushDto().getMobiles()
                        .stream()
                        .filter(Validator::isMobile)
                        .distinct()
                        .collect(Collectors.toList());
                log.info("本次短信计划发送:[{}]人，过滤无效手机号去重后，剩余[{}]人，明细[{}]",
                        aliPushSmsEventDto.getAliCameraSmsPushDto().getMobiles().size(),
                        mobs.size(),
                        JSONUtil.toJsonStr(aliPushSmsEventDto.getAliCameraSmsPushDto().getMobiles()));
                if (CollUtil.isNotEmpty(mobs)) {
                    msgService.pushFireAlarmConfirmSms(mobs,
                            aliPushSmsEventDto.getAliCameraSmsPushDto().getCameraName(),
                            aliPushSmsEventDto.getAliCameraSmsPushDto().getDistrictName()
                    );
                }
            }
        } catch (Exception e) {
            log.error("短信推送失败:原因[{}]", e.getMessage());
        }
    }

    @Async
    @EventListener
    public void pushAliNotice(String msg) {
        log.info("阿里云通知推送-推送时间[{}]-火情推送触发,msg[{}]", DateUtil.now(), msg);
        final CommFireAlarm alarm = JSONUtil.toBean(msg, CommFireAlarm.class);
        if (ObjectUtil.isNull(alarm)) {
            log.error("阿里云通知推送失败,火情信息解析失败:msg[{}]", msg);
            return;
        }
        final AliPushEventDto aliPushEventDto = buildDtoForAliNotice(alarm);
        try {
            //日志能构造出来说明有通知数据
            if (CollUtil.isNotEmpty(aliPushEventDto.getCommMsgCenterLog())) {
                final TimeInterval timeInterval = DateUtil.timer();
                //todo 采用批量插入数据的方式方法，注意后期数量达到500条记录，一定要对集合进行分组，否则mybatis 会触发底层阈值错误
                commMsgCenterLogDao.addBatch(aliPushEventDto.getCommMsgCenterLog());
                log.info("推送日志完成入库用时:[{}]毫秒", timeInterval.intervalRestart());
                final PushResponse pushResponse = AliyunPushMessageUtils.customizeAdvancedPush(
                        aliPushEventDto.getAliPushMessagePojo());
                log.info("msg:[{}],阿里通知推送情况:[{}]", msg, JSONUtil.toJsonStr(pushResponse));
            } else {
                log.error("阿里通知推送失败:因为无日志数据,msg[{}],aliPushEventDto[{}]", msg, JSONUtil.toJsonStr(aliPushEventDto));
            }
        } catch (Exception e) {
            log.error("阿里通知推送失败:原因:[{}]", e.getMessage());
        }
    }

    @Async
    @EventListener
    @SuppressWarnings("all")
    public void pushWebSocket(String msg) {
        final TimeInterval timeInterval = DateUtil.timer();
        log.info("websocket推送-推送时间[{}]-火情推送触发,msg[{}]", DateUtil.now(), msg);
        final CommFireAlarm alarm = JSONUtil.toBean(msg, CommFireAlarm.class);
        if (ObjectUtil.isNull(alarm)) {
            log.error("websocket推送失败,火情信息解析失败:msg[{}]", msg);
            return;
        }
        //获取websocket 推送内容
        final SendMessageDTO wsDto = buildDtoForWebSocket(alarm);
        try {
            if (wsDto != null) {
                final DataReturn dr = communicateFeignClient.sendMsg(wsDto);
                log.info("websocket:用时:[{}]毫秒,msg:[{}],推送情况:[{}]", timeInterval.intervalRestart(),
                        JSONUtil.toJsonStr(alarm), JSONUtil.toJsonStr(dr));
            }
        } catch (Exception e) {
            log.error("微服务内部错误：websocket推送失败!msg:[{}],dr:[{}]", msg, e.getMessage());
        }
    }

    //    @Async
//    @EventListener
    public void pushAliVoice(String msg) {
        log.info("阿里云语音推送-推送时间[{}]-火情推送触发,msg[{}]", DateUtil.now(), msg);
        final CommFireAlarm alarm = JSONUtil.toBean(msg, CommFireAlarm.class);
        if (ObjectUtil.isNull(alarm)) {
            log.error("阿里云语音推送失败,火情信息解析失败:msg[{}]", msg);
            return;
        }
        //获取语音推送内容 借用短信触发机制
        final AliPushSmsEventDto aliPushSmsEventDto = buildDtoForAliSms(alarm);
        try {
            if (ObjectUtil.isNotNull(aliPushSmsEventDto.getAliH5SmsPushDto())) {
                final List<String> mobs = aliPushSmsEventDto.getAliH5SmsPushDto().getMobiles()
                        .stream()
                        .filter(Validator::isMobile)
                        .distinct()
                        .collect(Collectors.toList());
                log.info("本次语音计划发送:[{}]人，过滤无效手机号去重后，剩余[{}]人，明细[{}]",
                        aliPushSmsEventDto.getAliH5SmsPushDto().getMobiles().size()
                        , mobs.size()
                        , JSONUtil.toJsonStr(aliPushSmsEventDto.getAliH5SmsPushDto().getMobiles()));
                if (CollUtil.isNotEmpty(mobs)) {
                    voicePushFacadeService.pushVoice(aliPushSmsEventDto.getAliH5SmsPushDto().getFireId(),
                            mobs,
                            aliPushSmsEventDto.getAliH5SmsPushDto().getStatus()
                    );
                    log.info("真实或疑似火情语音推送已完成");
                }
            }
            //todo 预留视频火情打电话
            if (ObjectUtil.isNotNull(aliPushSmsEventDto.getAliCameraSmsPushDto())) {

            }
        } catch (Exception e) {
            log.error("语音推送失败:原因[{}]", e.getMessage());
        }
    }

    /**
     * 火情数据插入业务主键表
     *
     * @param commFireAlarm
     */
    private void insertBusinessTable(CommFireAlarm commFireAlarm) {
        if (commFireAlarm.getDistrictCode() == null) {
            throw new ForestBaseException(ResultCode.OPERATE_ERROR.getCode(), "火情上报所在位置错误！");
        }
        //去掉村级行政区划
        String districtCode = geoQueryService.queryXiangByCun(commFireAlarm.getDistrictCode(),
                commFireAlarm.getDistrictCode().length());
        if (districtCode == null) {
            throw new ForestBaseException(ResultCode.OPERATE_ERROR.getCode(), "火情上报所在位置错误！");
        }
        //火情信息插入业务主键表
        BusinessTable businessTable = new BusinessTable();
        businessTable.setBusinessKey(String.valueOf(commFireAlarm.getId()));
        businessTable.setDistrictCode(districtCode);
        businessTable.setDistrictLength(String.valueOf(districtCode.length()));
        businessTableDao.insertSelective(businessTable);
        log.info("火情主表插入数据dto:[{}]", JSONUtil.toJsonStr(businessTable));
    }

    /**
     * 插入火情天气关联表数据
     * 直接cv 未修改
     *
     * @param fireId 火情id
     */
    private void insertWeatherInfo(Long fireId) {
        try {
            final String weatherInfo = RedisUtils.get(RedisKeyConstant.ONE_DAY_WEATHER);
            DailyWeather dailyWeather;
            if (weatherInfo == null) {
//                dailyWeather = weatherService.getOneDayWeather(address, 1, 5);
                //章伟发现根据api设定，start为1代表明天，为0是今天。插入火情应该取今天当下的天气，所以改成0
                dailyWeather = weatherService.getOneDayWeather(address, 0, 5);
                RedisUtils.getAndSetWithExpire(RedisKeyConstant.ONE_DAY_WEATHER, JSON.toJSONString(dailyWeather),
                        60 * 60 * 24);
            } else {
                dailyWeather = JSONObject.parseObject(weatherInfo, DailyWeather.class);
            }
            FireWeatherInfo fireWeatherInfo = FireWeatherInfo.builder()
                    .fireId(fireId)
                    .textDay(dailyWeather.getText_day())
                    .humidity(dailyWeather.getHumidity())
                    .high(dailyWeather.getHigh())
                    .low(dailyWeather.getLow())
                    .windDirection(dailyWeather.getWind_direction())
                    .windScale(dailyWeather.getWind_scale())
                    .windSpeed(String.format("%.4f", Double.parseDouble(dailyWeather.getWind_speed()) * 0.2778))
                    .rainfall(dailyWeather.getRainfall()).build();
            fireWeatherInfoDao.insert(fireWeatherInfo);
        } catch (Exception e) {
            log.error("处理天气异常,原因:[{}]", e.getMessage());
        }
    }

    /**
     * 查询并插入一张图数据
     *
     * @param fireAlarm 火情信息
     */
    private void insertOneMapInfo(final CommFireAlarm fireAlarm) {
        //这里查询是否报错，未考虑
        final CommFireOnemap commFireOnemap = commFireOnemapService.findByPoint(fireAlarm.getLongitude(),
                fireAlarm.getLatitude());
        if (ObjectUtil.isNotEmpty(commFireOnemap)) {
            commFireOnemap.setFireId(fireAlarm.getId());
            commFireOnemapService.add(commFireOnemap);
        }
    }


    /**
     * 重复火情判别
     *
     * @param fireAlarm 火情dto
     */
    private void repeatFireInfoChecked(final CommFireAlarm fireAlarm) {
        //deep clone
        final CommFireAlarm alarm = ObjectUtil.cloneByStream(fireAlarm);
        if (ObjectUtil.isNull(alarm.getOriginFireId())) {
            switch (alarm.getResource()) {
                //飞手
                case "1":
                    break;
                //护林员
                case "2":
                    verifySameFire(CollUtil.newArrayList("1", "2"), alarm.getLongitude(), alarm.getLatitude());
                    break;
                //卫星
                case "4":
                    break;
                //无人机
                case "5":
                    verifySameFire(CollUtil.newArrayList("3", "4", "5", "8", "9"), alarm.getLongitude(),
                            alarm.getLatitude());
                    break;
                //防火管理员
                case "6":
                    break;
                //电话接警
                case "7":
                    verifySameFire(CollUtil.newArrayList("6", "7"), alarm.getLongitude(), alarm.getLatitude());
                    break;
                //视频监控，3视频监控，8可见光，9热成像
                case "8":
                case "9":
                case "3":
                    verifySameFire(CollUtil.newArrayList("3", "4", "5", "8", "9"), alarm.getLongitude(),
                            alarm.getLatitude());
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 构造火情数据
     * 其中包括{是否删除,详细地址,行政区划编码}
     *
     * @param fireAlarm 待维护的火情对象
     *
     * @see CommFireAlarm#setHasDelete(Integer)
     * @see CommFireAlarm#setDetailAddress(String)
     * @see CommFireAlarm#setDistrictCode(String)
     */
    private void buildFireData(final CommFireAlarm fireAlarm) {
        //setHasDelete
        fireAlarm.setHasDelete(
                Convert.toInt(ObjectUtil.isNotEmpty(fireAlarm.getOriginFireId()) &&
                        fireAlarm.getOriginFireId() != BigDecimal.ZERO.longValue() &&
                        StrUtil.equals("6", fireAlarm.getResource()))
        );
        //获得经纬度  null 自动转换0
        final BigDecimal longitude = NumberUtil.toBigDecimal(fireAlarm.getLongitude());
        final BigDecimal latitude = NumberUtil.toBigDecimal(fireAlarm.getLatitude());
        if (!NumberUtil.equals(longitude, BigDecimal.ZERO) &&
                !NumberUtil.equals(latitude, BigDecimal.ZERO)) {
            //setDetailAddress
            if (StrUtil.isEmpty(fireAlarm.getDetailAddress())) {
                String address = StrUtil.EMPTY;
                try {
                    //84转成高德坐标系
                    double[] longitudeAndLatitudeDouble = LongitudeLatitudeTransisteUtils.gps84_To_Gcj02(
                            Convert.toDouble(fireAlarm.getLongitude()), Convert.toDouble(fireAlarm.getLatitude()));
                    //防止高德地图报错影响业务继续执行  主要防止 非国内经纬度
//                    address = GaodeUtils.queryAddressByLaAndLo(fireAlarm.getLongitude(), fireAlarm.getLatitude());
                    address = GaodeUtils.queryAddressByLaAndLo(Convert.toStr(longitudeAndLatitudeDouble[0]),
                            Convert.toStr(longitudeAndLatitudeDouble[1]));
                } catch (Exception e) {
                    log.error("获取高德地图服务解析失败,原因[{}]", e.getMessage());
                } finally {
                    fireAlarm.setDetailAddress(address);
                }
            }

            //setDistrictCode
            if (StrUtil.isEmpty(fireAlarm.getDistrictCode())) {
                String code = StrUtil.EMPTY;
                //调用地图防止抛出异常
                try {
                    final GeoCunDTO geoCunDTO = geoXzqhCunDao.getDistrictByPoint(fireAlarm.getLongitude(),
                            fireAlarm.getLatitude());
                    code = ObjectUtil.isNotNull(geoCunDTO) && StrUtil.isNotEmpty(geoCunDTO.getCun())
                            ? geoCunDTO.getCun() : StrUtil.EMPTY;
                } catch (Exception e) {
                    log.error("行政区划地图服务解析失败,原因[{}]", e.getMessage());
                } finally {
                    fireAlarm.setDetailAddress(code);
                }
            }
        }
    }

    /**
     * 校验火情是否已有上报记录
     *
     * @param resource  来源
     * @param longitude 经度
     * @param latitude  纬度
     *
     * @return true 已有上报记录
     */
    private void verifySameFire(List<String> resource, String longitude, String latitude) {
        //校验逻辑
        //相同来源火情校验
        List<CommFireAlarm> list = commFireAlarmDao.querySameSourceUnCompleteDisposalFire(resource);
        if (list != null && list.size() != 0) {
            List<CommFireAlarm> unCompleteDisposalFire = list.stream().filter(
                    e -> {
                        double distanceMeter = GeoUtils.GetDistanceTwo(Double.parseDouble(longitude),
                                Double.parseDouble(latitude), Double.parseDouble(e.getLongitude()),
                                Double.parseDouble(e.getLatitude()));
                        return distanceMeter < Double.parseDouble(limitDistance);
                    }
            ).collect(Collectors.toList());
            if (unCompleteDisposalFire.size() != 0) {
                //有相同来源数据
                throw new ForestBaseException(ResultCode.OPERATE_ERROR.getCode(), "该火情已有上报记录！");
            }
        }
        //不同来源火情校验
        list = commFireAlarmDao.queryNotSameSourceUnCompleteDisposalFire(resource);
        if (list != null && list.size() != 0) {
            List<CommFireAlarm> unCompleteDisposalFire = list.stream().filter(
                    e -> {
                        double distanceMeter = GeoUtils.GetDistanceTwo(Double.parseDouble(longitude),
                                Double.parseDouble(latitude), Double.parseDouble(e.getLongitude()),
                                Double.parseDouble(e.getLatitude()));
                        return distanceMeter < Double.parseDouble(limitDistance);
                    }
            ).collect(Collectors.toList());
            Set<String> set = new HashSet<>(list.size());
            if (unCompleteDisposalFire.size() > 1) {
                unCompleteDisposalFire.forEach(a -> {
                    String source = a.getResource();
                    set.add(source);
                });
            }
            if (set.size() > 2) {
                //来源已有2个，不允许新增
                throw new ForestBaseException(ResultCode.OPERATE_ERROR.getCode(), "该火情已有上报记录！");
            } else {
                //来源只有1个，可以新增
            }
        }
    }


    /**
     * 构造websocket 推送对象
     *
     * @param fireAlarm 火情dto
     *
     * @return 构造的dto对象
     */
    private SendMessageDTO buildDtoForWebSocket(CommFireAlarm fireAlarm) {
        final String fireSource = fireAlarm.getResource();
        //查询行政区划及以上防火管理员的ID集合
        final List<String> fireMangerIdList = CollUtil.<String>newArrayList();
        if (fireAlarm.getDistrictCode() != null && fireAlarm.getDistrictCode().length() >= 9) {
            //发送区一别的防火管理员
            fireMangerIdList.addAll(
                    fireAdminService.fireMangerIdListByDistrictCode(fireAlarm.getDistrictCode().substring(0, 6)));
            fireMangerIdList.addAll(
                    fireAdminService.fireMangerIdListByDistrictCode(fireAlarm.getDistrictCode().substring(0, 4)));

        } else {
            fireMangerIdList.addAll(fireAdminService.fireMangerIdList());
        }
        if (fireMangerIdList != null && fireMangerIdList.size() > 0) {
            //这里不用判空,null 不会进if ，会进 else
//            if (StrUtil.equalsAny(fireSource, "3")) {
//                return new SendMessageDTO("WEBWITHINUSERID", Convert.toStrArray(fireMangerIdList),
//                        JSON.toJSONString(DataReturn.ok(MsgIdentificationConstants.CAMERA_FIND_FIRE, null)));
//            }
            return new SendMessageDTO("WEBWITHINUSERID", Convert.toStrArray(fireMangerIdList),
                    JSON.toJSONString(DataReturn.ok(MsgIdentificationConstants.FIRE_ALARM, null)));
        } else {
            return null;
        }
       /* //这里不用判空,null 不会进if ，会进 else
        if (StrUtil.equalsAny(fireSource, "3", "8", "9")) {
            return new SendMessageDTO("WEB", JSON.toJSONString(DataReturn.ok(MsgIdentificationConstants.CAMERA_FIND_FIRE, null)));
        }
        return new SendMessageDTO("WEB", JSON.toJSONString(DataReturn.ok(MsgIdentificationConstants.FIRE_ALARM, null)));*/
    }

    /**
     * 构造阿里云通知 推送对象
     *
     * @param fireAlarm 火情dto
     *
     * @return 构造的dto对象
     */
    private AliPushEventDto buildDtoForAliNotice(CommFireAlarm fireAlarm) {
//        final String fireSource = fireAlarm.getResource();
//        final String detailAddress = fireAlarm.getDetailAddress();
        final AliPushEventDto aliPushEventDto = AliPushEventDto.builder().build();
//        //这里不用判空,null 不会进if ，会进 else
//        if (StrUtil.equalsAny(fireSource, "3", "8", "9")) {
//            //查询监控名称 --todo  不确定deviceId 是否有空的情况,及微服务内部调用问题
//            try {
//                final CameraVO cameraInfo = cameraInfoService.info(fireAlarm.getDeviceId().toString());
////                final SysUserRolePageDto dto = new SysUserRolePageDto();
////                dto.setRoleCode(RoleCodeConstants.ROLE_CODE_MANUAL_DUTY);
////                final Result<List<SysUserShortVo>> result = upmsFeignClient.getListForRole(dto);
//
//                List<SysUser> sysUsers = sysUserDAO.selectByCondition(null, null, null, true,
//                        RoleCodeConstants.ROLE_CODE_MANUAL_DUTY_ID, null, null, Integer.MAX_VALUE, 0);
//                if (CollectionUtil.isNotEmpty(sysUsers)) {
//                    final List<String> ids = sysUsers.stream().filter(vo -> ObjectUtil.isNotNull(vo.getId()))
//                            .map(vo -> Convert.toStr(vo.getId()))
//                            .distinct()
//                            .collect(Collectors.toList());
//                    final String title = NoticeTemplateConstants.CAMERA_PUSH_MANUAL_DUTY_TITLE;
//                    final String content = MessageFormat.format(NoticeTemplateConstants.CAMERA_PUSH_MANUAL_DUTY_CONTENT,
//                            cameraInfo.getCameraName(), detailAddress);
//                    //构造阿里推送通知 pojo
//                    final com.telit.common.pojo.AliPushMessagePojo aliPushMessagePojo = new com.telit.common.pojo.AliPushMessagePojo(
//                            MsgConstants.TARGET_ACCOUNT
//                            , MsgConstants.PUSH_TYPE_MESSAGE
//                            , MsgConstants.DEVICE_TYPE_ANDROID
//                            , NoticeTemplateConstants.CAMERA_PUSH_MANUAL_DUTY_TITLE
//                            , ids
//                            , new AliPushContentPojo(NoticeTypeConstants.NOTICE_TYPE_CAMERA_FIND_FIRE,
//                            JSONUtil.toJsonStr(
//                                    MessageFormat.format(NoticeTemplateConstants.CAMERA_PUSH_MANUAL_DUTY_CONTENT,
//                                            cameraInfo.getCameraName(), detailAddress))
//                    ));
//                    //构造日志记录
//                    final List<CommMsgCenterLog> logs = ids.stream().map(i ->
//                            new CommMsgCenterLog(content
//                                    //时间修改为本地时间
//                                    , "6", DateUtil.date(), "1",
//                                    fireAlarm.getFinderName(), title, Convert.toLong(i))
//                    ).collect(Collectors.toList());
//
//                    aliPushEventDto.setCommMsgCenterLog(logs)
//                            .setAliPushMessagePojo(aliPushMessagePojo);
//                }
//            } catch (Exception e) {
//                log.error("构造阿里云通知出错,原因:[{}]", e.getMessage());
//            }
//        } else {
//            if (StrUtil.equals("7", fireSource) && StrUtil.equals(fireAlarm.getStatus(), "3") && Convert.toBool(
//                    enablePushFireSms)) {
//                if (StrUtil.isNotEmpty(fireAlarm.getDistrictName()) && Convert.toBool(enablePushFireSms)) {
//                    List<String> fireMangerIdList = new ArrayList<>();
//                    if (fireAlarm.getDistrictCode() != null && fireAlarm.getDistrictCode().length() >= 9) {
//                        fireMangerIdList = fireAdminService.fireMangerIdListByDistrictCode(
//                                fireAlarm.getDistrictCode().substring(0, 9));
//                    } else {
//                        fireMangerIdList = fireAdminService.fireMangerIdList();
//                    }
////                    final List<String> fireMangerIdList = fireAdminService.fireMangerIdList();
//                    if (CollUtil.isNotEmpty(fireMangerIdList)) {
//                        final String content = fireAlarm.getDistrictName() + "地址发现了真实火情,请及时组织扑火工作";
//                        final String title = "火情报警";
//                        //构造阿里推送通知 pojo
//                        final com.telit.common.pojo.AliPushMessagePojo aliPushMessagePojo = new com.telit.common.pojo.AliPushMessagePojo(
//                                MsgConstants.TARGET_ACCOUNT,
//                                MsgConstants.PUSH_TYPE_MESSAGE,
//                                MsgConstants.DEVICE_TYPE_ANDROID,
//                                title,
//                                fireMangerIdList,
//                                new com.telit.common.pojo.AliPushContentPojo(NoticeTypeConstants.NOTICE_TYPE_NORMAL,
//                                        JSON.toJSONString(content)));
//                        //构造日志记录
//                        final List<CommMsgCenterLog> logs = fireMangerIdList.stream().map(i ->
//                                new CommMsgCenterLog(content
//                                        //时间修改为本地时间
//                                        , "4", DateUtil.date(), "1",
//                                        fireAlarm.getFinderName(), title, Convert.toLong(i))
//                        ).collect(Collectors.toList());
//                        aliPushEventDto.setCommMsgCenterLog(logs)
//                                .setAliPushMessagePojo(aliPushMessagePojo);
//                    } else {
//                        log.error("构造阿里云通知出错,原因:[{}],fireAlarm[{}]", "fireManagerIdList 无查询结果集",
//                                JSONUtil.toJsonStr(fireAlarm));
//                    }
//                }
//            } else {
        //疑似火情给防火管理员推送通知
        final List<String> list = CollUtil.<String>newArrayList();
        if (fireAlarm.getDistrictCode() != null && fireAlarm.getDistrictCode().length() >= 9) {
            //发送区一别的防火管理员
            list.addAll(
                    fireAdminService.fireMangerIdListByDistrictCode(fireAlarm.getDistrictCode().substring(0, 6)));
            list.addAll(
                    fireAdminService.fireMangerIdListByDistrictCode(fireAlarm.getDistrictCode().substring(0, 4)));
        } else {
            list.addAll(fireAdminService.fireMangerIdList());
        }
//                final List<String> list = fireAdminService.fireMangerIdList();
        if (CollUtil.isNotEmpty(list)) {
            String title = StrUtil.EMPTY;
            String content = StrUtil.EMPTY;
            if (ObjectUtil.isNotNull(fireAlarm.getFireJudgmentType())) {
                //视频监控发现的火情
                if (fireAlarm.getFireJudgmentType() == 1 || fireAlarm.getFireJudgmentType() == 2) {
                    content =
                            fireAlarm.getFinderName() + "视频监控发现了" + fireAlarm.getDistrictName() + "地址的火情，请前往查看";
                    title = "视频监控火情报警";
                }
            }
            // todo 会不会存在 FireJudgmentType() 即不为null，被发下属方法替换掉，，请查证
            switch (fireAlarm.getResource()) {
                //护林员疑似火情
                case "1":
                    content = "护林员" + fireAlarm.getFinderName() + "给你上报了" + fireAlarm.getDistrictName()
                            + "地址的火情，请前往查看";
                    title = "你有新的上报火情";
                    break;
                //飞手疑似火情
                case "2":
                            content = "飞手" + fireAlarm.getFinderName() + "给你上报了" + fireAlarm.getDistrictName()
                                    + "地址的火情，请前往查看";
                            title = "你有新的上报火情";
                            break;
                        //电话接警
                        case "6":
                            content = "防火管理员" + (fireAlarm.getMobileReceiverName() == null ? ""
                                    : fireAlarm.getMobileReceiverName()) + "通过电话接警上报" + fireAlarm.getFinderName()
                                    + "发现了" + fireAlarm.getDistrictName() + "地址的火情，请前往查看";
//                            content = "防火管理员通过电话接警上报" + fireAlarm.getFinderName() + "发现了" + fireAlarm.getDistrictName() + "地址的火情，请前往查看";
                            title = "你有新的上报火情";
                            break;
                        //防火管理员疑似火情
                        case "7":
                            content = "防火管理员" + fireAlarm.getFinderName() + "发现了" + fireAlarm.getDistrictName()
                                    + "地址的火情，请前往查看";
                            title = "你有新的上报火情";
                            break;
                        default:
                            break;
            }
            //构造阿里推送通知 pojo
            final com.telit.common.pojo.AliPushMessagePojo aliPushMessagePojo = new com.telit.common.pojo.AliPushMessagePojo(
                    MsgConstants.TARGET_ACCOUNT,
                    MsgConstants.PUSH_TYPE_MESSAGE,
                    MsgConstants.DEVICE_TYPE_ANDROID,
                    title,
                    list,
                    new AliPushContentPojo(NoticeTypeConstants.NOTICE_TYPE_NORMAL, JSON.toJSONString(content)));
            //构造日志记录
            final String finalContent = content;
            final String finalTitle = title;
            final List<CommMsgCenterLog> logs = list.stream().map(i ->
                    new CommMsgCenterLog(finalContent
                            //时间修改为本地时间
                            , "3", DateUtil.date(), "1",
                            fireAlarm.getFinderName(), finalTitle, Convert.toLong(i))
            ).collect(Collectors.toList());
            aliPushEventDto.setCommMsgCenterLog(logs)
                    .setAliPushMessagePojo(aliPushMessagePojo);

        } else {
            log.error("构造阿里云通知出错,原因:[{}],fireAlarm[{}]", "fireManagerIdList 无查询结果集",
                    JSONUtil.toJsonStr(fireAlarm));
        }
//            }
//        }
        return aliPushEventDto;
    }

    /**
     * 构造阿里云短信推送对象
     *
     * @param fireAlarm 火情dto
     *
     * @return 构造的dto对象
     */
    @SuppressWarnings("all")
    private AliPushSmsEventDto buildDtoForAliSms(CommFireAlarm fireAlarm) {
        final String fireSource = fireAlarm.getResource();
        final String detailAddress = fireAlarm.getDetailAddress();
        final AliPushSmsEventDto aliPushSmsEventDto = AliPushSmsEventDto.builder().build();
        //村级乡镇级防火管理员
        List<SysUser> sysUsers = sysUserDAO.selectByCondition(null, null, fireAlarm.getDistrictCode(), true,
                RoleCodeConstants.ROLE_CODE_FIRE_MANAGER_ID, null, null, Integer.MAX_VALUE, 0);
        if (CollectionUtil.isNotEmpty(sysUsers)) {
            final List<String> mobiles = sysUsers.stream().filter(
                    vo -> ObjectUtil.isNotNull(vo.getId()) && StrUtil.isNotEmpty(vo.getMobile()))
                    .map(SysUser::getMobile)
                    .distinct()
                    .collect(Collectors.toList());
            if (CollUtil.isEmpty(mobiles)) {
                log.error("暂无人员需要收到视频推送");
            } else {
                aliPushSmsEventDto.setAliH5SmsPushDto(AliH5SmsPushDto.builder()
                        .fireId(fireAlarm.getId())
                        .status(2)
                        .mobiles(mobiles)
                        .build());
            }
        }
        return aliPushSmsEventDto;
    }

}